home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 2
/
Atari Mega Archive CD - Volume 2.iso
/
minix
/
up1510b.tgz
/
up1510b
/
src
/
commands
/
ps.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-07-23
|
19KB
|
628 lines
/* ps - print status Author: Peter Valkenburg */
/* ps.c, Peter Valkenburg (valke@psy.vu.nl), january 1990.
*
* This is a V7 ps(1) look-alike for MINIX 1.5.0. It can use a database with
* information on system addresses as an extra, and has some additional fields.
* It does not support the 'k' option (i.e. cannot read memory from core file).
* If you want to compile this for non-IBM PC architectures, the header files
* require that you have your CHIP, MACHINE etc. defined.
*
* VERY IMPORTANT NOTE:
* To use ps, kernel/kernel, fs/fs, and mm/mm must be in the /usr/src
* (or the #includes below must be changed). Furthermore, all of
* must contain symbol tables. This can be arranged using the -s flag
* and the ast program. For example in fs, one would have
*
* asld -s -i -o fs $l/head.s $(obj) $l/libc.a $l/end.s >symbol.out
* ast -X fs # include symbol.out in fs
*
*/
/*
* Most fields are similar to V7 ps(1), except for CPU, NICE, PRI which are
* absent, RECV which replaces WCHAN, and RUID and PGRP that are extras.
* The info is obtained from the following fields of proc, mproc and fproc:
* F - kernel status field, p_flags
* S - kernel status field, p_flags; mm status field, mp_flags (R if p_flags
* is 0; Z if mp_flags == HANGING; T if mp_flags == STOPPED; else W).
* UID - mm eff uid field, mp_effuid
* RUID - mm real uid field, mp_realuid
* PID - mm pid field, mp_pid
* PPID - mm parent process index field, mp_parent (used as index in proc).
* PGRP - mm process group id mp_procgrp
* ADDR - kernel physical text address, p_map[T].mem_phys
* SZ - kernel physical stack address + stack size - physical text address,
* p_map[S].mem_phys + p_map[S].mem_len - p_map[T].mem_phys
* RECV - kernel process index field for message receiving, p_getfrom
* If sleeping, mm's mp_flags, or fs's fp_task are used for more info.
* TTY - fs controlling tty device field, fs_tty.
* TIME - kernel user + system times fields, user_time + sys_time
* CMD - system process index (converted to mnemonic name obtained by reading
* tasktab array from kmem), or user process argument list (obtained by
* reading reading stack frame; the resulting address is used to get
* the argument vector from user space and converted into a concatenated
* argument list).
*/
#include <minix/config.h>
#include <limits.h>
#include <sys/types.h>
#include <minix/const.h>
#undef EXTERN /* <minix/const.h> defined this */
#define EXTERN /* so we get proc, mproc and fproc */
#include <minix/type.h>
#include "../kernel/const.h"
#include "../kernel/type.h"
#include "../kernel/proc.h"
#undef printf /* kernel's const.h defined this */
#include "../mm/mproc.h"
#include "../fs/fproc.h"
#include "../fs/const.h"
#undef printf /* fs's const.h defined this */
/*----- ps's local stuff below this line ------*/
#include <minix/com.h>
#include <fcntl.h>
#include <a.out.h>
#include <stdio.h>
#define mindev(dev) (((dev)>>MINOR) & 0377) /* yield minor device */
#define majdev(dev) (((dev)>>MAJOR) & 0377) /* yield major device */
#define TTY_MAJ 4 /* fixed tty major device */
/* macro to convert memory offsets to rounded kilo-units */
#define off_to_k(off) ((unsigned) (((off) + 512) / 1024))
/* what we think the relevant identifiers in the namelists are */
#define ID_PROC "_proc" /* from kernel namelist */
#define ID_MPROC "_mproc" /* from mm namelist */
#define ID_FPROC "_fproc" /* from fs namelist */
#define ID_TASKTAB "_tasktab" /* from kernel namelist */
/*
* Structure for system address info (also layout of ps's database).
*/
typedef struct {
struct nlist ke_proc[2], ke_tasktab[2];
struct nlist mm_mproc[2];
struct nlist fs_fproc[2];
} sysinfo_t;
sysinfo_t sysinfo; /* sysinfo holds actual system info */
#define NAME_SIZ (sizeof(sysinfo.ke_proc[0].n_name)) /* 8 chars */
/* what we think the identfiers of the imported variables in this program are */
#define PROC proc
#define MPROC mproc
#define FPROC fproc
#define TASKTAB tasktab
/* default paths for system binaries */
#if (CHIP == M68000)
#define KERNEL_PATH "/usr/src/kernel/kernel.mix"
#define MM_PATH "/usr/src/mm/mm.mix"
#define FS_PATH "/usr/src/fs/fs.mix"
#else
#define KERNEL_PATH "/usr/src/kernel/kernel"
#define MM_PATH "/usr/src/mm/mm"
#define FS_PATH "/usr/src/fs/fs"
# endif
#define KMEM_PATH "/dev/kmem" /* opened for kernel proc table */
#define MEM_PATH "/dev/mem" /* opened for mm/fs + user processes */
int kmemfd, memfd; /* file descriptors of [k]mem */
#define DBASE_PATH "/etc/psdatabase" /* path of ps's database */
#define DBASE_MODE 0644 /* mode for ps's database */
/* paths for system binaries (not relevant if database is used) */
char *kpath = KERNEL_PATH;
char *mpath = MM_PATH;
char *fpath = FS_PATH;
struct tasktab tasktab[NR_TASKS + INIT_PROC_NR + 1]; /* task table */
/*
* Short and long listing formats:
*
* PID TTY TIME CMD
* ppppp ttmmm:ss ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
*
* F S UID PID PPID PGRP ADDR SZ RECV TTY TIME CMD
* fff s uuu ppppp ppppp ppppp aaaa sss rrrrrrrrrrr ttmmm:ss cccccccccccccccccccc
* (RAMDSK) FS
* or
* (PAUSE) MM
*/
#define S_HEADER " PID TTY TIME CMD\n"
#define S_FORMAT "%5d %3s%3ld:%02ld %.62s\n"
#define L_HEADER " F S UID PID PPID PGRP ADDR SZ RECV TTY TIME CMD\n"
#define L_FORMAT "%3o %c %3d %5d %5d %5d %4d %3d %11s %3s%3ld:%02ld %.19s\n"
struct pstat { /* structure filled by pstat() */
dev_t ps_dev; /* major/minor of controlling tty */
uid_t ps_ruid; /* real uid */
uid_t ps_euid; /* effective uid */
pid_t ps_pid; /* process id */
pid_t ps_ppid; /* parent process id */
int ps_pgrp; /* parent process id */
int ps_flags; /* kernel flags */
int ps_mflags; /* mm flags */
int ps_ftask; /* (possibly pseudo) fs suspend task */
char ps_state; /* process state */
size_t ps_tsize; /* text size (in bytes) */
size_t ps_dsize; /* data size (in bytes) */
size_t ps_ssize; /* stack size (in bytes) */
off_t ps_text; /* physical text offset */
off_t ps_data; /* physical data offset */
off_t ps_stack; /* physical stack offset */
int ps_recv; /* process number to receive from */
time_t ps_utime; /* accumulated user time */
time_t ps_stime; /* accumulated system time */
char *ps_args; /* concatenated argument string */
};
/* ps_state field values in pstat struct above */
#define Z_STATE 'Z' /* Zombie */
#define W_STATE 'W' /* Waiting */
#define S_STATE 'S' /* Sleeping */
#define R_STATE 'R' /* Runnable */
#define T_STATE 'T' /* stopped (Trace) */
/*
* Tname returns mnemonic string for dev_nr. This is "?" for unknown maj/min
* pairs. It is utterly rigid in this implementation...
*/
char *tname(dev_nr)
{
static char buf[4];
if (majdev(dev_nr) != TTY_MAJ || /* yuchhh! */
mindev(dev_nr) < 0 || mindev(dev_nr) >= 100)
return "? ";
if (mindev(dev_nr) == 0)
return "co ";
sprintf(buf, "t%-2d", mindev(dev_nr));
return buf;
}
/* return canonical task name of task p_nr; overwritten on each call */
char *taskname(p_nr)
{
char *cp;
if (p_nr < -NR_TASKS || p_nr > INIT_PROC_NR)
return "?";
/* strip trailing blanks for right-adjusted output */
for (cp = tasktab[p_nr + NR_TASKS].name; *cp != '\0'; cp++)
if (*cp == ' ')
break;
*cp = '\0';
return tasktab[p_nr + NR_TASKS].name;
}
/*
* Prrecv prints the RECV field for process with pstat buffer pointer bufp.
* This is either "ANY", "taskname", or "(blockreason) taskname".
*/
char *prrecv(bufp)
struct pstat *bufp;
{
char *blkstr, *task; /* reason for blocking and task */
static char recvstr[20];
if (bufp->ps_recv == ANY)
return "ANY";
task = taskname(bufp->ps_recv);
if (bufp->ps_state != S_STATE)
return task;
blkstr = "?";
if (bufp->ps_recv == MM_PROC_NR) {
if (bufp->ps_mflags & PAUSED)
blkstr = "pause";
else if (bufp->ps_mflags & WAITING)
blkstr = "wait";
}
else if (bufp->ps_recv == FS_PROC_NR) {
if (-bufp->ps_ftask == XOPEN)
blkstr = "xopen";
else if (-bufp->ps_ftask == XPIPE)
blkstr = "xpipe";
else
blkstr = taskname(-bufp->ps_ftask);
}
(void) sprintf(